package auxiliary_classes;

public class Vector4 extends Matrix {
	public Vector4(){
		super(4, 1);
		double[] vals = {0.0, 0.0, 0.0, 1.0};
		this.setColumn(0, vals);
	}
	
	public Vector4(double x, double y, double z){
		super(4, 1);
		double[] vals = {x, y, z, 1.0};
		this.setColumn(0, vals);
	}
	
	public double getX(){
		return this.getCell(0, 0);
	}
	
	public double getY(){
		return this.getCell(1, 0);
	}
	
	public double getZ(){
		return this.getCell(2, 0);
	}
	
	public void setX(double val){
		this.setCell(0, 0, val);
	}
	
	public void setY(double val){
		this.setCell(0, 0, val);
	}
	
	public void setZ(double val){
		this.setCell(0, 0, val);
	}
	
	public String toString(){ //print x and y values in coordinate format
		return ("(" + this.getX() + ", " + this.getY() + ", " + this.getZ() + ")");
	}

	public String roundToString() {
         return ("(" + (int) this.getX() + ", " + (int) this.getY() + ", " + (int) this.getZ() + ")");
    } 
	
	public double[] getData(){
		double[] temp = new double[3];
		for (int i = 0; i < 3; i++){
			temp[i] = this.getCell(i, 1);
		}
		return temp;
	}
	
	//returns the magnitude (AKA norm, length) of the vector
	public double magnitude(){
		return Math.sqrt(Math.pow(this.getCell(0, 0), 2) + 
						 Math.pow(this.getCell(1, 0), 2) + 
						 Math.pow(this.getCell(2, 0), 2));
	}
	
	//Normalizes (reduces length to 1) the vector
	public void normalize(){
		double norm = this.magnitude();
		if (norm != 0){
			this.scale(1/norm);
		}
	}
	
	//Returns the this vectors normal (same angle, length 1)
	public Vector4 normal(){
		Vector4 temp = (Vector4) this.copy();
		double norm = this.magnitude();
		if (norm != 0){
			temp.scale(1/norm);
		}
		return temp;
	}
	
	//Finds the dot product of two vectors
	public double dot(Vector4 other){
		return this.getCell(0, 0) * other.getCell(0, 0) +
			   this.getCell(1, 0) * other.getCell(1, 0) +
			   this.getCell(2, 0) * other.getCell(2, 0);
	}
	
	//Returns the cross product vector of this and other
	public Vector4 cross(Vector4 other){
		Vector4 temp = new Vector4();
		double[] data = {this.getCell(1, 0)*other.getCell(2, 0) - this.getCell(2, 0)*other.getCell(1, 0),
                         this.getCell(2, 0)*other.getCell(0, 0) - this.getCell(0, 0)*other.getCell(2, 0),
                         this.getCell(0, 0)*other.getCell(1, 0) - this.getCell(1, 0)*other.getCell(0, 0),
                         1};
		temp.setColumn(0, data);
		return temp;
	}
	
	//Calculates the cross product and replaces this with the result
	public void inPlaceCross(Vector4 other) {
		double[] data = {this.getCell(1, 0)*other.getCell(2, 0) - this.getCell(2, 0)*other.getCell(1, 0),
                		 this.getCell(2, 0)*other.getCell(0, 0) - this.getCell(0, 0)*other.getCell(2, 0),
                		 this.getCell(0, 0)*other.getCell(1, 0) - this.getCell(1, 0)*other.getCell(0, 0),
                		 1};
		this.setColumn(0, data);
	}
	
	public double distance(Vector4 other){
		return Math.sqrt(Math.pow(this.getCell(0, 0) - other.getCell(0 , 0), 2) +
						 Math.pow(this.getCell(1, 0) - other.getCell(1 , 0), 2) +
						 Math.pow(this.getCell(2, 0) - other.getCell(2 , 0), 2));
	}
}
